/**
 * 
 */
package com.taobao.pageapi.controller;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * @author hujingfei.pt@taobao.com
 *
 */
public class GwtRpcController extends RemoteServiceServlet implements
		Controller, ServletContextAware {

	private static final long serialVersionUID = -2072075062900397883L;

	private ServletContext servletContext;

    private RemoteService upperService;

    private Class<? extends RemoteService> upperServiceClass;

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        super.doPost(request, response);
        return null;
    }

    @Override
    public String processCall(String payload) throws SerializationException {
        try {
            RPCRequest rpcRequest = RPC.decodeRequest(payload, this.upperServiceClass);

            // delegate work to the spring injected service
            return RPC.invokeAndEncodeResponse(this.upperService, rpcRequest.getMethod(), rpcRequest.getParameters());
        } catch (IncompatibleRemoteServiceException ex) {
            getServletContext().log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
            return RPC.encodeResponseForFailure(null, ex);
        }
    }

    @Override
    public ServletContext getServletContext() {
        return servletContext;
    }

    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }

    public void setUpperService(RemoteService upperService) {
        this.upperService = upperService;
        this.upperServiceClass = this.upperService.getClass();
    }
}
